/*
 * @Descripttion: 
 * @version: 
 * @Author: TT
 * @Date: 2023-06-01 22:39:55
 * @LastEditors: TT
 * @LastEditTime: 2023-06-02 09:25:57
 */

import "dart:io";
import "package:ffmpeg_kit_flutter/ffmpeg_kit.dart";
import "package:ffmpeg_kit_flutter/ffmpeg_session.dart";
import "package:flutter_hls_parser/flutter_hls_parser.dart";
import "package:hzy_common_module/hzy_common_module.dart";
import "package:image_gallery_saver/image_gallery_saver.dart";
import "package:path_provider/path_provider.dart";

class DownloadM3U8Util {
  DownloadM3U8Util._();

  static final DownloadM3U8Util instance = DownloadM3U8Util._();
  List<String> downLoadUrl = [];

  // 传入m3u8下载地址
  Future<void> downloadM3u8(String url) async {
    dprint("DownloadUtil, _url=$url");
    if (downLoadUrl.contains(url)) {
      dprint("已进入下载队列");
      return;
    }
    final String savePath = await _getSavePath(); // 存储路径

    downLoadUrl.add(url);
    final String host = url.substring(0, url.lastIndexOf("/"));
    final String m3u8FileName =
        url.substring(url.lastIndexOf("/") + 1); // m3u8文件名带后缀.  xxx.m3u8
    final String m3u8Path =
        "$savePath/$m3u8FileName"; // m3u8保存绝对路径  /abc/../xxx.m3u8
    final String m3u8Name = m3u8FileName.split(".").first; // m3u8文件名不带后缀  xxx

    final Response response =
        await Dio().download(url, m3u8Path, onReceiveProgress: (count, total) {
      dprint(count);
      dprint(total);
    });

    if (response.statusCode != 200) {
      dprint("下载 m3u8 失败 _url=$url");
      downLoadUrl.remove(url);
      return;
    }
    // video文件夹不存在则创建
    Directory directory = Directory("$savePath/video/");
    if (!directory.existsSync()) {
      directory.createSync();
    }

    HlsPlaylist? playList;
    try {
      playList = await HlsPlaylistParser.create()
          .parse(Uri.parse(url), await File(m3u8Path).readAsLines());
    } on ParserException catch (e) {
      dprint(e);
    }

    dprint(playList);

    if (playList is HlsMediaPlaylist) {
      // 读取m3u8文件的URL信息
      final mediaPlaylistUrls = playList.segments.map((it) => it.url);
      dprint(mediaPlaylistUrls);
      for (var value in mediaPlaylistUrls) {
        // value  oux02488.ts
        String tsUrl = "$host/$value";
        File file = File("$savePath/$value");
        if (!file.existsSync()) {
          file.create();
        }
        dprint("下载ts地址 url=$tsUrl， file.path=${file.path}");
        Response response = await Dio().download(
          tsUrl,
          file.path,
          onReceiveProgress: (count, total) {
            dprint(count);
            dprint(total);
          },
        );
        dprint(response);
        if (response.statusCode != 200) {
          downLoadUrl.remove(url);
          return;
        }
      }
      dprint("已下载完所有ts视频");
      String cmd =
          '-allowed_extensions ALL -i $m3u8Path  "$savePath/video/$m3u8Name.mp4"';
      dprint(cmd);

      ///合并ts为mp4
      FFmpegKit.executeAsync(cmd, (FFmpegSession session) {
        showtoastmsg("下载成功", type: 1);
        downLoadUrl.remove(url);
        // 保存到相册
        ImageGallerySaver.saveFile("$savePath/video/$m3u8Name.mp4")
            .then((value) {
          // 删除临时路径的文件
          File file = File("$savePath/video/$m3u8Name.mp4");
          file.deleteSync();
        });
      });
    }
  }

  /// 获取存储路径
  static Future<String> _getSavePath() async {
    final directory = Platform.isAndroid
        ? await getExternalStorageDirectory()
        : await getApplicationDocumentsDirectory();
    return directory!.path;
  }
}
